/*
 * ScreenPopup class.
 * popup 창을 layer로 실행할 수 있도록 한다.
 * popup창(layer)이 올라오면 부모창(popup을 호출한 창)에 이벤트가 갈 수 없도록 한다.
 *
 * 부모창 -> 투명 iframe 스크린 -> popup창 의 순서로 배치하여 투명 iframe이 부모창의 이벤트를 막도록 한다.
 *
 * 이것을 사용하기 위해서는 prototype.js, WindowUtil.js, ScreenPopup.css, scriptaculous.js 가 필요하다.
 *
 * 사용법:
 *    var p = new ScreenPopup({method: "get|post", url: "/url/to/load", params: "para1=val1&para2=val2...", left: left, top: top, width: width, height: height});
 *    p.showPopup();
 *
 *    p.closePopup();
 *
 * method: url 호출 방식(get 또는 post) - default = get
 * url: 화면에 표시되어야 하는 내용의 url
 * params: url이 호출될 때 전달되는 parameter
 * left: 화면이 표시될 x 좌표(지정이 안되면 화면의 가운데).
 * top: 화면이 표시될 y 좌표(지정이 안되면 화면의 가운데).
 * width: 화면에 표시되어야 하는 내용의 넓이. 선택적
 * height: 화면에 표시되어야 하는 내용의 높이. 선택적
 * innerHTML: 화면에 표시될 내용을 url에서 얻어오지 않고 직접 문자열로 할당함. 선택적
 * popupHandler: url을 호출하면서 오류가 발생될 경우에 이 창을 닫을 수 있도록 하기 위하여 
 *              생성된 ScreenPopup 을 참조하는 변수를 이용하여 closePopup() 메소드를 호출해야 한다.
 *              closePopup() 메소드를 eval 을 사용하여 실행할 수 있도록 팝업을 참조하는 변수명을 문자열로 넘긴다.
 * evalScripts: Ajax 호출로 출력된 페이지에 스크립트가 포함되어 있다면, 그것을 실행하도록 할 것인지 결정한다.
 *
 * 예제:
 *    var p = new ScreenPopup({url: "/cms/ProductMisc.ajax", params: "_method=viewProductRegMethod"});
 *    var p = new ScreenPopup({url: "/cms/ProductMisc.ajax", params: "_method=viewProductRegMethod", width: 400});
 *    var p = new ScreenPopup({innerHTML: "...", left: 100, width: 400});
 *    var p = new ScreenPopup({url: "...", left: 100, width: 400, popupHandler: "p"});
 *
 * 이것은 상품등록을 위한 선택옵션 페이지를 출력한다.
 *
 * ScreenPopup 이 생성되면 그것은 드래그가 가능하게 생성되어서 마우스로 창을 끌고 다닐 수 있다.
 * 드래그가 가능하게 되면 입력 상자가 아닌 부분의 아무데서나 드래그가 가능해서 스크롤바가 있는 입력 상자에서는
 * 약간의 문제가 있을 수 있다. 따라서 창의 헤더 부분에서만 드래그가 가능하게 해줄 필요가 있는데,
 * 특정한 영역에서만 드래그 기능을 활성화하기 위해서 "drag-handle" 라는 id를 가지는 것을 만들 필요가 있다.
 * 팝업으로 보여지는 페이지에서 id가 drag-handle 이라는 엘리먼트가 없으면,
 * 팝업창의 모든 영역에서 드래그를 가능하게 되고, drag-handle 이라는 id의 엘리먼트가 있으면
 * 그 영역에서만 드래그가 가능하게 될 것이다.
 *
 */

var ScreenPopup = Class.create();
ScreenPopup.prototype = {
    url: null,
    params: "",
    method: 'get',
    iframePopup: null,
    divPopup: null,
    divWidth: null,
    divHeight: null,
    divLeft: null,
    divTop: null,
    divInnerHTML: null,
    popupHandler: null,
    objDrag: null,
    evalScripts: true,

    /**
     * {
     *   method: 'get|post'
     *   url: 'url',
     *   params: 'para1=val1&para2=val2&para3=val3...',
     *   left: left,
     *   top: top,
     *   width: width,
     *   height: height,
     *   innerHTML: 'inner html',
     *   popupHandler: 'popupHandler',
     *   evalScripts: false
     * }
     */
    initialize: function (initParams) {
//        alert($H(initParams).inspect());
        if (initParams.method) this.method = initParams.method.toLowerCase();
        if (initParams.url) this.url = initParams.url;
        if (initParams.params) this.params = initParams.params;
        if (initParams.left) this.divLeft = initParams.left;
        if (initParams.top) this.divTop = initParams.top;
        if (initParams.width) this.divWidth = initParams.width;
        if (initParams.height) this.divHeight = initParams.height;
        if (initParams.innerHTML) this.divInnerHTML = initParams.innerHTML;
        if (initParams.popupHandler) this.popupHandler = initParams.popupHandler;
        if (initParams.evalScripts != null) this.evalScripts = initParams.evalScripts;
    },

    // post방식의 요청을 해야할 경우가 있으므로 method파라미터를 추가합니다.
    // method ajax의 호출 method, 인자가 없으면 default 'get'입니다.
    showPopup: function() {
        // transparent iframe screen
        this.iframePopup = document.createElement("iframe") ;
        this.iframePopup.className = "screenPopup";
        var docDim = WindowUtil.getDocDimention();
        this.iframePopup.style.width = docDim.width + "px";
        this.iframePopup.style.height = docDim.height + "px";
        this.iframePopup.style.visibility = "visible";
        document.body.insertBefore(this.iframePopup, null);
        
        // real popup div
        this.divPopup = document.createElement("div");
        this.divPopup.id = "divScreenPopup-" + (new Date()).getTime();
        this.divPopup.className = "screenPopup";
        if (this.divWidth) this.divPopup.style.width = this.divWidth + "px";
        if (this.divHeight) this.divPopup.style.height = this.divHeight + "px";
        document.body.insertBefore(this.divPopup, null);
        if (this.divInnerHTML) this.divPopup.innerHTML = this.divInnerHTML;
        if (this.url) {
            var pms = "";
            var pbd = "";
            if (this.method == "post") pbd = this.params;
            else pms = this.params;
            
            var req = new Ajax.Updater(
                        this.divPopup,
                        this.url, 
                        {
                            method: this.method,
                            asynchronous: false,
                            parameters: pms,
                            postBody: pbd,
                            evalScripts: this.evalScripts,
                            requestHeaders: {"x-request-target": "ScreenPopup", "x-popup-handler": this.popupHandler}
                        }
                    );
        }
        if (this.divLeft) {
            this.divPopup.style.left = this.divLeft + "px";
        } else {
            var x = Math.max((document.body.clientWidth - this.divPopup.offsetWidth) / 2, 0);
            this.divPopup.style.left = (x + document.body.scrollLeft) + "px";
        }
        if (this.divTop) {
            this.divPopup.style.top = this.divTop + "px";
        } else {
            var y = Math.max((document.body.clientHeight - this.divPopup.offsetHeight) / 2, 0);
            this.divPopup.style.top = (y + document.body.scrollTop) + "px";
        }
        this.divPopup.style.visibility = "visible";
        // turn on draggable effects using scriptaculous
        if (Scriptaculous) {
            var handles = null;
            try { handles = Element.getElementsBySelector(this.divPopup, "#drag-handle"); } catch (e) {}
            this.objDrag = new Draggable(this.divPopup.id, {starteffect:null, endeffect:null, handle:(handles && handles.length > 0 ? handles[0] : null)});
        }
    },
    closePopup: function() {
        // turn off draggable effects
        if (this.objDrag) {
            this.objDrag.destroy();
            this.objDrag = null;
        }
        // remove popup div
        if (this.divPopup && this.divPopup.parentNode) {
            this.divPopup.parentNode.removeChild(this.divPopup);
            this.divPopup = null;
        }

        // remove iframe
        if (this.iframePopup && this.iframePopup.parentNode) {
            this.iframePopup.parentNode.removeChild(this.iframePopup);
            this.iframePopup = null;
        }
    },
    setDivInnerHTML: function(innerHTML) {
        if (this.divPopup) this.divPopup.innerHTML = innerHTML;
    }
}
